#include <stdint.h>


typedef uint8_t     Bit8;
typedef uint16_t    Bit16;
typedef uint32_t    Bit32;
typedef uint64_t    Bit64;

typedef char        Num;
typedef short       Num2;
typedef long int    Num4;
typedef long long   Num8;
typedef char*       Str;

#include "y.tab.h"

typedef union  _values_ values;
typedef struct _expr_ tree;
typedef struct _assign_ assign;
typedef struct _funccall_ funccall;
typedef struct _operation_ operation;
typedef struct _variable_ variable;
typedef struct _array_ array;
typedef struct _tree_table_ treeTable;

typedef enum {
    EXPR_BINARY=1,
    EXPR_DEF_VAR, //创建变量
    EXPR_VAR_CONSTANT, //变量or常量
    EXPR_ASSIGN,//赋值
    EXPR_DEF_FUNC,
    EXPR_CALL_FUNC,
} exprType; // 语句类型

typedef enum {
    OP_ADD = 1,//加 
    OP_SUB,   //减
    OP_MUL,   //乘
    OP_DIV,   //除
    OP_ADD_INC, //var++
    OP_INC_ADD, //++var
    OP_DEC_SUB, //var--
    OP_SUB_DEC, //--var
} OperationType; //计算类型

typedef enum {
    DATA_TYPE_NULL = 1,
    DATA_TYPE_NUMBER_1,
    DATA_TYPE_NUMBER_2,
    DATA_TYPE_NUMBER_4,
    DATA_TYPE_NUMBER_8,
    DATA_TYPE_F_NUMBER_4,
    DATA_TYPE_F_NUMBER_8,
    DATA_TYPE_STRING,
} DataType; // 数据类型

typedef enum {
    ATTR_CONSTANT, //常量
    ATTR_VAR, //变量
    ATTR_RETURN, //返回
} VarAttr; // 变量属性

typedef union _f32_
{
    Bit32   f2d;
    float   f;
}F32;
typedef union _f64_
{
    struct 
	{
		Bit32 l;
		Bit32 h;
	}mem;
    double   f;
}F64;
union _values_ {
    Num     *number;
    Num2    *number2;
    Num4    *number4;
    Num8    *number8;
    F32     *f_number4;
    F64     *f_number8;
    Str     string;
};

struct _variable_ {
    DataType   type;
    char    *name;
    values  *value;
    array   *arr;
    Num is_float; //0: 不是, 1:单精度, 2:双精度
    Num4    F_NO;
    VarAttr attr;
    Num4    position_stack;
};


struct _operation_{
    OperationType type;
    char prec; //优先
    tree *left;
    tree *right;
};

struct _assign_{
    tree *left;
    tree *right;
};
struct _funccall_{
    char *name;
    Num4 params_count;
    treeTable *params;
};
struct _expr_ {
    exprType type;
    union {
        variable    *var_v;
        operation   *operation_v;
        assign      *assign_v;
        funccall    *func_call_v;
    }entity;
};
struct _tree_table_ {
    tree *node;
    treeTable *next;
};

struct _array_
{
    Num2 layers;
    Num2 count; //总数
    Num2 *base;
    Num2 *map;
};


#define GET_ARRAY_LEN(a,b) if(a->type==DATA_TYPE_NUMBER_1) b=a->oval.on; \
    else if(a->type==DATA_TYPE_NUMBER_2)  b=a->oval.on2;

#define VarPutArr(var,k)     var->arr=k;
#define VarPutName(var,k)    var->name=k;
#define VarPutValue(var,k)   var->value=k;
//#define VarPutIsFloat(var,k) var->is_float=k;
#define VarPutAttr(var,k)    var->attr=k;
#define VarPutFigure(var,k)  var->number_attr=k;
#define VarPutFNo(var,k)  var->F_NO=k;

Num2 findConstant(char *str);
DataType Token2DataType(enum yytokentype token, enum yytokentype is_f);

treeTable *createTreeTab();
tree *createTree(exprType type);
void linkTree(tree *node);
treeTable * linkTree2(tree *node, treeTable *list);
operation *createOperation(OperationType type, tree *l, tree *r);
assign *createAssign(tree *l, tree *r);
funccall *createFunccall(char *name, treeTable *params);
variable *createVariable(enum yytokentype accuracy, enum yytokentype data_type, char *s, array *arr);
tree *createConstant(DataType type, values *val, array *arr);
values *createValues(DataType type, void *data);
array *editArray(array *arr, Num2 number);
variable *mallocVariable();
values *createValuesFloat(double num);
DataType GetFloatType(double num);
Num8 Str2Num8(char *str); //atoll
double Str2Double(char *str);
double Var2Double(variable *var);